home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Internet
/
Collection of Internet.iso
/
infosrvr
/
dev
/
libhtml_.tar
/
HMDoc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-21
|
4KB
|
252 lines
/* HMDoc.c -- HyperMedia Document base class
*/
/* implements ... */
#include "HMDoc.h"
/* uses ... */
#include "HTMLdtd.h"
#include "SGML.h"
#include "object.h"
static HMFileWriterProc fileWriter;
static HMWriterProc writer;
static HMDeleteProc delete;
static HMStartTagProc startTag;
static HMEndTagProc endTag;
static HMDataProc data;
HMDoc_Class InCore = {fileWriter, writer,
delete,
startTag, endTag, data,
html_entity_text};
typedef struct{
char* gi;
int content;
int nattrs;
HMBinding* attrs;
}Tag;
typedef struct _cell{
struct _cell *first, *rest, *up;
}Cons;
struct _HMDoc{
Cons* root;
Cons* here;
};
/* constructors */
static HMDoc*
fileWriter(fp)
FILE* fp;
{
return 0; /* this class doesn't write to files */
}
static HMDoc*
writer(out, write)
HMStream out;
HMWriteProc* write;
{
return 0; /* this class doesn't write to streams */
}
HMDoc*
InCore_new()
{
HMDoc* this = NEW(HMDoc, 1);
this->root = 0;
this->here = 0;
return this;
}
/* destructors */
static VOID Tag_free PARAMS((Tag* it));
static VOID
element_free(this)
Cons* this;
{
Cons* c;
if(this->first){
Cons* next;
Tag_free((Tag*)this->first);
for(c = this->rest; c; c = next){
element_free(c->first);
next = c->rest;
FREE(c);
}
}else{
FREE(this->rest); /* data */
}
FREE(this);
}
static VOID
delete(this)
HMDoc* this;
{
if(this->root)
element_free(this->root);
}
/* building routines */
static Tag*
Tag_new(gi, content, attrs, nattrs)
CONST char* gi;
CONST HMBinding attrs[];
int nattrs;
{
Tag* this = NEW(Tag, 1);
int total = strlen(gi) + 1;
int i;
char* p;
for(i = 0; i<nattrs; i++)
total += strlen(attrs[i].name) + 1
+ strlen(attrs[i].value) + 1;
this->gi = NEW(char, total);
this->content = content;
this->attrs = NEW(HMBinding, nattrs);
this->nattrs = nattrs;
strcpy(this->gi, gi);
p = this->gi;
while(*p++);
for(i=0; i<nattrs; i++){
strcpy(this->attrs[i].name = p, attrs[i].name);
while(*p++);
strcpy(this->attrs[i].value = p, attrs[i].value);
while(*p++);
}
return this;
}
static VOID
Tag_free(this)
Tag* this;
{
FREE(this->gi);
FREE(this->attrs);
}
static Cons*
cons(car, cdr, parent)
VOIDPTR car;
VOIDPTR cdr;
Cons* parent;
{
Cons* this = NEW(Cons, 1);
this->first = (Cons*)car;
this->rest = (Cons*)cdr;
this->up = parent;
return this;
}
static VOID
attach(this, element, data)
HMDoc* this;
Tag* element;
CONST char* data;
{
Cons* it = cons(element, data);
if(this->here){
Cons* cell = cons(it, 0, this->here->up);
this->here->rest = cell;
this->here = cell;
}else{
this->root = this->here = it;
}
}
static int
startTag(this, gi, attributes, nattrs)
HMDoc* this;
CONST char* gi;
CONST HMBinding attributes[];
int nattrs;
{
int c = HTML_content(gi);
Tag* nt = Tag_new(gi, c, attributes, nattrs); /* content? @@*/
attach(this, nt, 0);
return c;
}
static VOID
endTag(this, gi)
HMDoc* this;
CONST char* gi;
{
if(this->here && this->here->up)
this->here = this->here->up;
}
static VOID
data(this, data, qty)
HMDoc* this;
CONST char* data;
int qty;
{
if(this->here){
char* nd = NEW(char, qty+sizeof(int));
*((int*)nd) = qty;
memcpy(nd + sizeof(int), data, qty);
attach(this, 0, nd);
}
}
/* traverse the document */
static VOID
element_traverse(this, dest, docclass)
Cons* this;
HMDoc* dest;
HMDoc_Class* docclass;
{
Cons* c;
if(this->first){
Tag* t = (Tag*)(this->first);
(docclass->startTag)(dest, t->gi, t->attrs, t->nattrs);
if(t->content != SGML_EMPTY){
for(c = this->rest; c; c = c->rest)
element_traverse(c->first, dest, docclass);
(docclass->endTag)(dest, t->gi);
}
}else{
int q = *((int*)(this->rest));
char* d = ((char*)(this->rest)) + sizeof(int);
(docclass->data)(dest, d, q);
}
}
VOID
InCore_traverse(this, that, c)
HMDoc* this;
HMDoc* that;
HMDoc_Class* c;
{
element_traverse(this->root, that, c);
}